package com.rbac.admin.service.system.impl;

import com.rbac.admin.entity.system.SystemMenu;
import com.rbac.admin.entity.system.SystemRoleMenu;
import com.rbac.admin.mapper.system.RoleMenuMapper;
import com.rbac.admin.service.system.MenuService;
import com.rbac.admin.service.system.RoleMenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 角色菜单服务实现类
 *
 * @author rbac-admin
 * @since 2024-07-18
 */
@Slf4j
@Service
public class RoleMenuServiceImpl implements RoleMenuService {
    
    @Autowired
    private RoleMenuMapper roleMenuMapper;
    
    @Autowired
    private MenuService menuService;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean assignRoleMenus(String roleId, List<String> menuIds) {
        // 先删除该角色所有菜单关联
        roleMenuMapper.deleteByRoleId(roleId);
        
        // 如果菜单ID列表为空，则只做删除操作
        if (menuIds == null || menuIds.isEmpty()) {
            return true;
        }

        // 获取完整的菜单树（包含所有菜单的父级菜单）
        Set<String> completeMenuIds = new HashSet<>(menuIds);
        addParentMenus(completeMenuIds, menuIds);
        
        log.info("角色[{}]分配菜单：原始菜单数={}, 包含父级菜单后={}", roleId, menuIds.size(), completeMenuIds.size());
        
        // 批量插入新的角色菜单关联
        AtomicInteger idGenerator = new AtomicInteger((int) System.currentTimeMillis());
        List<SystemRoleMenu> roleMenus = completeMenuIds.stream()
                .map(menuId -> {
                    SystemRoleMenu roleMenu = new SystemRoleMenu();
                    // 生成临时ID，实际插入时会由数据库自动生成
                    // 这里只是为了避免使用null导致错误
                    roleMenu.setId(idGenerator.incrementAndGet());
                    roleMenu.setRoleId(roleId);
                    roleMenu.setMenuId(menuId);
                    roleMenu.setCreateTime(LocalDateTime.now());
                    return roleMenu;
                }).collect(Collectors.toList());
        
        return roleMenuMapper.batchInsert(roleMenus) > 0;
    }
    
    /**
     * 递归添加所有父级菜单ID
     * 
     * @param resultSet 结果集，用于存储包含父级菜单在内的所有菜单ID
     * @param menuIds 当前要处理的菜单ID列表
     */
    private void addParentMenus(Set<String> resultSet, List<String> menuIds) {
        // 创建一个新的列表，存储需要查找父级的菜单ID
        List<String> parentIdsToFind = new ArrayList<>();
        
        // 获取当前菜单列表中的所有菜单详情
        for (String menuId : menuIds) {
            SystemMenu menu = menuService.getById(menuId);
            if (menu != null && menu.getParentId() != null && 
                !menu.getParentId().equals("0") && !resultSet.contains(menu.getParentId())) {
                // 如果有父级菜单且不是根菜单，且还未添加到结果集
                parentIdsToFind.add(menu.getParentId());
                resultSet.add(menu.getParentId());
            }
        }
        
        // 如果还有父级菜单需要处理，递归处理
        if (!parentIdsToFind.isEmpty()) {
            addParentMenus(resultSet, parentIdsToFind);
        }
    }
} 